package linker

import (
	"risc-v/ld/pkg/utils"
)

// ReadFile 根据上下文信息读取指定文件内的 ObjectFile
// 并将其存储到 Context 参数中
func ReadFile(ctx *Context, file *File) {
	fileType := GetFileType(file.Content)
	switch fileType {
	//一个单独的Object 文件
	case FileTypeObject:
		// 不在链接库里面 inLib 参数为 false
		ctx.ObjectFiles = append(ctx.ObjectFiles, CreateObjectFile(ctx, file, false))
	case FileTypeArchive:
		// 归档文件（静态链接库），分别读取其中的每一个Object文件
		for _, f := range ReadArchiveMember(file) {
			utils.Assert(GetFileType(f.Content) == FileTypeObject)
			ctx.ObjectFiles = append(ctx.ObjectFiles, CreateObjectFile(ctx, f, true))
		}
	default:
		utils.Fatal("unknown file type")
	}
}

// CreateObjectFile 打开 ObjectFile 并处理
// inLib 参数表示 ObjectFile 是否在静态链接库中
func CreateObjectFile(ctx *Context, file *File, inLib bool) *ObjectFile {
	// 检查文件兼容性
	CheckFileCompatibility(ctx, file)

	obj := NewObjectFile(file, !inLib)
	obj.Parse(ctx) // object 文件的初始化工作

	return obj
}

// ReadInputFile 读入静态库文件和 ObjectFile
// 提取有效参数到 Context
func ReadInputFile(ctx *Context, remaining []string) {
	for _, arg := range remaining {
		var ok bool
		if arg, ok = utils.RemovePrefix(arg, "-l"); ok {
			// .a 文件
			ReadFile(ctx, FindLibrary(ctx, arg))
		} else {
			ReadFile(ctx, MustNewFile(arg))
		}
	}
}
